{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Python for Finance"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Analyze Big Financial Data**\n",
    "\n",
    "O'Reilly (2014)\n",
    "\n",
    "Yves Hilpisch"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Mathematical Tools"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pylab import plt\n",
    "plt.style.use('seaborn')\n",
    "import matplotlib as mpl\n",
    "mpl.rcParams['font.family'] = 'serif'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Approximation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "uuid": "460b709e-eed1-48e4-b3ad-d07377ea5de6"
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Integration"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "uuid": "6a38567d-4a2d-464f-8de3-7687e1d2916d"
   },
   "outputs": [],
   "source": [
    "import scipy.integrate as sci"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "uuid": "0954e5b6-9874-4bad-a2fb-28273a015e4a"
   },
   "outputs": [],
   "source": [
    "def f(x):\n",
    "    return np.sin(x) + 0.5 * x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "uuid": "afb6151f-5743-4950-980e-18047e066ebc"
   },
   "outputs": [],
   "source": [
    "a = 0.5  # left integral limit\n",
    "b = 9.5  # right integral limit\n",
    "x = np.linspace(0, 10)\n",
    "y = f(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "uuid": "ad78923f-e4c1-4381-9a24-33b4f1ea3c56"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.axis.YTick at 0x27ab75c5d00>,\n",
       " <matplotlib.axis.YTick at 0x27ab75c58e0>]"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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vICNG48vw9WkiZ927YK0axegbdsA551XvLffgQM2lixxsGCBg4ULHezcGR7O6XAE6d17O4MGbYm5VV0k9sVSAOoUaAUKBOCRRxIIBGz07btN4RchHI4Q11yTyjXXpLJp0znMnNmQZcvqsGWLky1b4IMPwo+rXz9I27YBrrgiQHJyCLs9vBLN0f/abOFNjFetcrBokYO1a0+cv5CU5OOqq/Zz++2bSEk5YsFPKiKFKQAr0N//7mLNGic1auRyxx2m1eXIaTRtmskf/rAan8/G1q1VWbeuBmvXVmP9+urs3u1m924706YVbdURlytA8+YHad36AK1bp9OkySGd7haJIArACrJ3r43nnw9PcP7d79aSlBR9y3PFE5crRLNmmTRrlsnNN4e79127KrN2bQ22bKmK328nFKLgy1bwFT72vPOyad06nebNM3C7dW1PJFIpACvIE08kcORIeK3Ptm33W12OFJPDAQ0bZtGwYdlvgSUi1tCg6wrwv/85mTPHRWKij3vvXWd1OSIiggKw3GVlweOPh099DhliUrOm5vyJiEQCBWA5e+UVNz//7KBJk0x69dphdTkiIlJAAViOdu+28c474e5v+PC1Mbmqv4hItFIAlqMXXkjA67XRseNemjbNtLocEREpRAFYTtassfPppy6czgBDhmy0uhwRETmJArAchELh9T4B+vTZQUpK7OzmLSISKxSA5WDePAfffhve223QoC1WlyMiIqehACxjfj+MHh0e+HLrrZtJTtZixyIikUgBWMamTnWxZYuTlJQcTXsQEYlgCsAylJ0NL74YXij5zjs34nJp4WMRkUilACxDEya4SU93YBgZXH11qtXliIjIr1AAlpHUVBsTJ4a7v9/+dj22Em/RKCIiFUEBWEZefNFNXp6d9u1TadEiw+pyRETkLBSAZWD9ejsffeTC4Qhy552a9C4iEg0UgGXg+ecTCIVs9Oq1k3r1cqwuR0REikABWEorV9qZN8+Jx+Pnlls2W12OiIgUkQKwlP72t6NLnm2nalWvxdWIiEhRKQBL4fvv7Xz1lZPERB/9+2+zuhwRESkGBWApjB0b7v769t1OlSpa8kxEJJooAEto8WJYsMBJUpKP/v23W12OiIgUk7MoDzIMoytwE/ALEDJN85mT7p8ENC50U0vgcqAW8DCwGjCA70zTfLfQc94KbAaaAY+Yphk1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\n",
      "text/plain": [
       "<Figure size 504x360 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "from matplotlib.patches import Polygon\n",
    "\n",
    "fig, ax = plt.subplots(figsize=(7, 5))\n",
    "plt.plot(x, y, 'b', linewidth=2)\n",
    "plt.ylim(ymin=0)\n",
    "\n",
    "# area under the function\n",
    "# between lower and upper limit\n",
    "Ix = np.linspace(a, b)\n",
    "Iy = f(Ix)\n",
    "verts = [(a, 0)] + list(zip(Ix, Iy)) + [(b, 0)]\n",
    "poly = Polygon(verts, facecolor='0.7', edgecolor='0.5')\n",
    "ax.add_patch(poly)\n",
    "\n",
    "# labels\n",
    "plt.text(0.75 * (a + b), 1.5, r\"$\\int_a^b f(x)dx$\",\n",
    "         horizontalalignment='center', fontsize=20)\n",
    "\n",
    "plt.figtext(0.9, 0.075, '$x$')\n",
    "plt.figtext(0.075, 0.9, '$f(x)$')\n",
    "\n",
    "ax.set_xticks((a, b))\n",
    "ax.set_xticklabels(('$a$', '$b$'))\n",
    "ax.set_yticks([f(a), f(b)])\n",
    "# tag: sin_integral\n",
    "# title: Example function with integral area\n",
    "# size: 50"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Numerical Integration"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "uuid": "6d3aa9c8-58c0-46a3-a89f-ca471a1f83e4"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "24.366995967084602"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sci.fixed_quad(f, a, b)[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "uuid": "0ddebba6-5357-4ce9-b829-d752132d12df"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "24.374754718086752"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sci.quad(f, a, b)[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "uuid": "3b1779d6-c831-449d-964f-e2cc869847e7"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "24.374754718086713"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sci.romberg(f, a, b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "uuid": "5499809d-f2b1-4cc9-8808-511f4e82c5ed"
   },
   "outputs": [],
   "source": [
    "xi = np.linspace(0.5, 9.5, 25)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "uuid": "aec239bc-cdd9-4477-b47c-4d0136ed686d"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "24.352733271544516"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sci.trapz(f(xi), xi)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "uuid": "ce33e420-5143-4d54-b23f-0040f54723fc"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "24.37496418455075"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sci.simps(f(xi), xi)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Integration by Simulation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "uuid": "bb840eb2-0e13-40eb-aea7-0f106dcf9f41"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "24.804762279331463\n",
      "26.522918898332378\n",
      "26.265547519223976\n",
      "26.02770339943824\n",
      "24.99954181440844\n",
      "23.881810141621663\n",
      "23.527912274843253\n",
      "23.507857658961207\n",
      "23.67236746066989\n",
      "23.679410416062886\n",
      "24.424401707879305\n",
      "24.239005346819056\n",
      "24.115396924962802\n",
      "24.424191987566726\n",
      "23.924933080533783\n",
      "24.19484212027875\n",
      "24.117348378249833\n",
      "24.100690929662274\n",
      "23.76905109847816\n"
     ]
    }
   ],
   "source": [
    "for i in range(1, 20):\n",
    "    np.random.seed(1000)\n",
    "    x = np.random.random(i * 10) * (b - a) + a\n",
    "    print(np.sum(f(x)) / len(x) * (b - a))"
   ]
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
